﻿using System;
using System.Web;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Threading;
using System.Web.Mvc;
using AutoMapper;
using CashOrCard.DTO;
using CashOrCard.Helper;
using CashOrCard.Models;
using CashOrCard.Repository;
using ImageResizer;
using ImageResizer.Plugins;
using ImageResizer.Resizing;
using ImageResizer.Util;
using CashOrCard.Extensions;

namespace CashOrCard.Controllers.Admin
{
    public class AdvtAdminController : Controller
    {
        private readonly IBaseRepository<AdvtSite> _advtRep;
        private readonly IBaseRepository<SiteType> _siteType;
        private readonly IBaseRepository<Country> _country;
        private readonly IBaseRepository<CardType> _cardType;
        private readonly IBaseRepository<CashType> _cashType;
        private readonly IBaseRepository<AdvtSiteImage> _advtSiteImg;
        private readonly IBaseRepository<User> _userRep;
        public AdvtAdminController(IBaseRepository<AdvtSite> advtRep,
                                   IBaseRepository<SiteType> siteType,
                                   IBaseRepository<Country> country,
                                   IBaseRepository<CardType> cardType,
                                   IBaseRepository<CashType> cashType,
                                   IBaseRepository<User> userRep,
                                   IBaseRepository<AdvtSiteImage> advtSiteImg
                                   )
        {
            this._advtRep = advtRep;
            this._siteType = siteType;
            this._country = country;
            this._cardType = cardType;
            this._cashType = cashType; ;
            this._userRep = userRep;
            _advtSiteImg = advtSiteImg;

        }

        private User getCurrentUser()
        {
            string email = Common.CurrentUserEamil;
            User curUser = _userRep.LoadEntities(x => x.Email == email && x.IsEnable == true).FirstOrDefault();
            return curUser;
        }

        [CashOrCardAuthorizeExtension(AllowPermissions = "sitemanagement_access", ErrorView = "PermissionDenied")]
        public ActionResult Index()
        {
            var advtsites = _advtRep.LoadEntities(x => x.IsEnable);
            return View(advtsites.ToList());
        }

        [CashOrCardAuthorizeExtension(AllowPermissions = "sitemanagement_access", ErrorView = "PermissionDenied")]
        public ActionResult GetAllAdvt(AdvtSiteInput searchInput)
        {
            int pageIndex = Request["page"] == null ? 1 : int.Parse(Request["page"]);
            int pageSize = Request["rows"] == null ? 10 : int.Parse(Request["rows"]);
            int total = 0;
            bool isAdmin = Common.IsAdmin;
            IQueryable<AdvtSite> advtsites = null;
            if (isAdmin)
            {
                advtsites = _advtRep.LoadPagerEntities(pageSize, pageIndex, out total,
                                                       x =>
                                                       (string.IsNullOrEmpty(searchInput.SiteName) ||
                                                        x.SiteName.ToLower().Contains(searchInput.SiteName.ToLower()))
                                                       && (searchInput.SiteTypeId == 0 ||
                                                           x.SiteTypeId == searchInput.SiteTypeId)
                                                       && x.IsEnable
                                                       , true, u => u.AdvtSiteId);
            }
            else
            {
                var curUser = getCurrentUser();
                var tempsites = curUser.AdvtSites.Where(x => (string.IsNullOrEmpty(searchInput.SiteName) || x.SiteName.ToLower().Contains(searchInput.SiteName.ToLower()))
                                                              && x.IsEnable);
                total = tempsites.Count();
                advtsites = tempsites.Skip(pageSize * (pageIndex - 1)).Take(pageSize).OrderBy(o => o.AdvtSiteId).AsQueryable();
            }
            var inputList = advtsites.Select(advt => new AdvtSiteInput
                                               {
                                                   AdvtSiteId = advt.AdvtSiteId,
                                                   SiteName = advt.SiteName,
                                                   SiteDescription = advt.SiteDescription,
                                                   SiteTypeId = advt.SiteTypeId,
                                                   Address = advt.Address,
                                                   SiteURL = advt.SiteURL,
                                                   PhoneNumber = advt.PhoneNumber,
                                                   SiteAmount = advt.SiteAmount,
                                                   SiteRate = advt.SiteRate,
                                                   SiteThumb = advt.SiteThumb,
                                                   SiteGallery = advt.SiteImages.Select(x => x.Path).ToArray(),
                                                   CountryId = advt.CountryId,
                                                   SiteTypeName = advt.SiteType.SiteTypeName,
                                                   CountryName = advt.Country.CountryName,
                                                   CardAccepted = advt.CardTypes.Select(x => x.CardTypeId).ToArray(),
                                                   CashAccepted = advt.CashTypes.Select(x => x.CashTypeId).ToArray(),
                                                   latitude = advt.latitude,
                                                   longitude = advt.longitude,
                                                   Promotions = string.Format("<a lengh='0' href='/PromotionAdmin/Index?advtId={0}'>View / Edit</a>", advt.AdvtSiteId)
                                               }).ToList();
            var result = new { total = total, rows = inputList, success = true };
            return Json(result, JsonRequestBehavior.AllowGet);
        }

        public ActionResult GetSiteType()
        {
            var sitetypes = _siteType.LoadEntities(x => x.IsEnable);
            return Json(sitetypes);
        }

        public ActionResult GetCountry()
        {
            var countries = _country.LoadEntities(x => x.IsEnable);
            return Json(countries);
        }

        public ActionResult GetCards()
        {
            var cards = from card in _cardType.LoadEntities(x => x.IsEnable)
                        select new { CardTypeId = card.CardTypeId, CardTypeName = card.CardTypeName };
            return Json(cards);
        }
        public ActionResult GetCashType()
        {
            var cashTypes = from cashs in _cashType.LoadEntities(x => x.IsEnable)
                            select new { CashTypeId = cashs.CashTypeId, CashTypeName = cashs.CashTypeName };
            return Json(cashTypes);
        }


        [CashOrCardAuthorizeExtension(AllowPermissions = "sitemanagement_access", ErrorView = "PermissionDenied")]
        public ActionResult AddNewAdvt(AdvtSiteInput advtSiteDto)
        {
            var curUser = getCurrentUser();
            bool added = false;
            string message = string.Empty;
            decimal totalAmount = curUser.Amount;
            decimal tookAmlunt = curUser.AdvtSites.Where(x => x.IsEnable).Sum(o => o.SiteAmount);
            decimal restAmout = totalAmount - tookAmlunt;
            if (advtSiteDto.SiteAmount > restAmout)
            {
                added = false;
                message = string.Format("Your accout only have {0} rest, please input valid amount or you need to recharg money", restAmout);
            }
            else
            {
                Mapper.CreateMap<AdvtSiteInput, AdvtSite>();
                AdvtSite advtSite = Mapper.Map<AdvtSiteInput, AdvtSite>(advtSiteDto);
                advtSite.CreateDate = DateTime.Now;
                advtSite.SiteRate = 0;
                advtSite.IsEnable = true;
                advtSite.CardTypes = new List<CardType>();
                advtSite.CashTypes = new List<CashType>();
                advtSite.SiteImages = new List<AdvtSiteImage>();

                advtSite.CardTypes = _cardType.LoadEntities(x => x.IsEnable && advtSiteDto.CardAccepted.ToList().Contains(x.CardTypeId)).ToList();
                advtSite.CashTypes = _cashType.LoadEntities(x => x.IsEnable && advtSiteDto.CashAccepted.ToList().Contains(x.CashTypeId)).ToList();

                foreach (var siteGallery in advtSiteDto.SiteGallery)
                {
                    advtSite.SiteImages.Add(new AdvtSiteImage
                    {
                        IsEnable = true,
                        Path = siteGallery,
                        UploadDate = DateTime.Now
                    });
                }
                curUser.AdvtSites.Add(advtSite);
                added = _userRep.Save();
                message = "Site add successfully";
            }
            return Json(new { Success = added, Message = message });
        }

        [CashOrCardAuthorizeExtension(AllowPermissions = "sitemanagement_access", ErrorView = "PermissionDenied")]
        public ActionResult UpdateAdvt(AdvtSiteInput advtSiteDto)
        {
            var curUser = getCurrentUser();
            bool updated = false;
            string message = string.Empty;
            decimal totalAmount = curUser.Amount;
            decimal tookAmlunt = curUser.AdvtSites.Where(x => x.IsEnable).Sum(o => o.SiteAmount);
            bool isAdmin = Common.IsAdmin;
            var advtSite = new AdvtSite();
            if (isAdmin)
            {
                advtSite = _advtRep.LoadEntities(x => x.AdvtSiteId == advtSiteDto.AdvtSiteId).FirstOrDefault();
            }
            else
            {
                advtSite = curUser.AdvtSites.FirstOrDefault(x => x.AdvtSiteId == advtSiteDto.AdvtSiteId);
            }
            decimal restAmout = totalAmount - tookAmlunt + advtSite.SiteAmount;
            if (advtSiteDto.SiteAmount > restAmout)
            {
                updated = false;
                message = string.Format("Your accout only have {0} rest, please input valid amount or you can recharg money", restAmout);
            }
            else
            {
                advtSite.SiteName = advtSiteDto.SiteName;
                advtSite.SiteDescription = advtSiteDto.SiteDescription;
                advtSite.SiteTypeId = advtSiteDto.SiteTypeId;
                advtSite.Address = advtSiteDto.Address;
                advtSite.PhoneNumber = advtSiteDto.PhoneNumber;
                advtSite.SiteAmount = advtSiteDto.SiteAmount;
                //advtSite.SiteRate = advtSiteDto.SiteRate;
                advtSite.SiteThumb = advtSiteDto.SiteThumb;
                advtSite.CountryId = advtSiteDto.CountryId;
                advtSite.latitude = advtSiteDto.latitude;
                advtSite.longitude = advtSiteDto.longitude;
                advtSite.SiteURL = advtSiteDto.SiteURL;
                advtSite.SiteImages = new List<AdvtSiteImage>();

                // Delete all cardtyps and cashtypes           
                advtSite.CardTypes.Clear();
                advtSite.CashTypes.Clear();
                advtSite.SiteImages.Clear();
                _userRep.Save();

                foreach (var siteGallery in advtSiteDto.SiteGallery)
                {
                    advtSite.SiteImages.Add(new AdvtSiteImage
                    {
                        IsEnable = true,
                        Path = siteGallery,
                        UploadDate = DateTime.Now
                    });
                }

                if (advtSiteDto.CardAccepted != null && advtSiteDto.CardAccepted.Count() > 0)
                {
                    advtSite.CardTypes = new List<CardType>();
                    advtSite.CardTypes = _cardType.LoadEntities(x => x.IsEnable && advtSiteDto.CardAccepted.ToList().Contains(x.CardTypeId)).ToList();
                }
                if (advtSiteDto.CashAccepted != null && advtSiteDto.CashAccepted.Count() > 0)
                {
                    advtSite.CashTypes = new List<CashType>();
                    advtSite.CashTypes = _cashType.LoadEntities(x => x.IsEnable && advtSiteDto.CashAccepted.ToList().Contains(x.CashTypeId)).ToList();
                }
                updated = _userRep.Save();
                message = "Advt update successfully";
            }
            return Json(new { Success = updated, Message = message });
        }

        [CashOrCardAuthorizeExtension(AllowPermissions = "sitemanagement_access", ErrorView = "PermissionDenied")]
        public ActionResult DeleteAdvt(int id)
        {
            var asite = _advtRep.Get(id);
            asite.IsEnable = false;
            var result = _advtRep.UpdateEntities(asite);
            if (result)
                return Content("success");
            else
                return Content("Some errors occured.");
        }

        [HttpPost]
        [CashOrCardAuthorizeExtension(AllowPermissions = "sitemanagement_access", ErrorView = "PermissionDenied")]
        public string Upload(FormCollection fc)
        {
            string newFileName = string.Empty;
            string newDirName = string.Empty;
            if (Request.Files.Count != 0)
            {
                Thread.Sleep(500);
                HttpPostedFileBase file = Request.Files[0];

                string Extension = Path.GetExtension(file.FileName);

                newFileName = Guid.NewGuid().ToString() + Extension;
                newDirName = Guid.NewGuid().ToString();
                if (!Directory.Exists(Server.MapPath("/AdvtImages/" + newDirName)))
                {
                    Directory.CreateDirectory(Server.MapPath("/AdvtImages/" + newDirName));
                }
                string name = Path.Combine(Server.MapPath("/AdvtImages/" + newDirName + "/"), newFileName);

                file.SaveAs(name);

                GenerateVersions(name);
            }
            Thread.Sleep(500);
            return "/AdvtImages/" + newDirName + "/" + newFileName;
        }

        public IList<string> GenerateVersions(string original)
        {
            Dictionary<string, string> versions = new Dictionary<string, string>();
            //Define the versions to generate and their filename suffixes.
            versions.Add("_thumb", "width=150&height=76&scalemode=both&bgcolor=FFF&format=jpg"); 
            versions.Add("_medium", "width=692&height=284&scalemode=both&bgcolor=FFF&format=jpg");
            versions.Add("_large", "width=500&height=500&scalemode=both&bgcolor=F8F8F8&format=jpg");

            string basePath = ImageResizer.Util.PathUtils.RemoveExtension(original);

            //To store the list of generated paths
            List<string> generatedFiles = new List<string>();

            //Generate each version
            foreach (string suffix in versions.Keys)
                //Let the image builder add the correct extension based on the output file type
                generatedFiles.Add(ImageBuilder.Current.Build(original, basePath + suffix,
                  new ResizeSettings(versions[suffix]), false, true));

            return generatedFiles;
        }

    }
}
